package com.uyayo.cms.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.uyayo.cms.entity.CmsChannel;
import com.uyayo.cms.mapper.CmsChannelMapper;
import com.uyayo.cms.model.CmsChannelCondition;
import com.uyayo.cms.service.CmsChannelService;
import com.uyayo.framework.common.exception.CodeMultipleException;
import com.uyayo.framework.common.exception.ParentNotFoundException;
import com.uyayo.framework.pagehelper.pojo.OrderBy;
import com.uyayo.framework.pagehelper.pojo.PageBean;
import com.uyayo.framework.pagehelper.util.OrderByUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.entity.Example.Criteria;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;


@Service("cmsChannelService")
public class CmsChannelServiceImpl implements CmsChannelService {


	private final CmsChannelMapper cmsChannelMapper;

	@Autowired
	public CmsChannelServiceImpl(CmsChannelMapper cmsChannelMapper) {
		this.cmsChannelMapper = cmsChannelMapper;
	}


	@Override
	public CmsChannel getChannelById(Long id){
		return cmsChannelMapper.selectByPrimaryKey(id);
	}
	

	@Override
	public List<CmsChannel> selectChannel(CmsChannelCondition cmsChannelCondition) {
		Example example = new Example(CmsChannel.class);
		Example.Criteria criteria = example.createCriteria();
		if(Objects.nonNull(cmsChannelCondition.getHiddenStatus())){
			criteria.andEqualTo("hiddenStatus",cmsChannelCondition.getHiddenStatus());
		}
		if(Objects.nonNull(cmsChannelCondition.getValidStatus())){
			criteria.andEqualTo("validStatus",cmsChannelCondition.getValidStatus());
		}
		if(Objects.nonNull(cmsChannelCondition.getParentId())){
			criteria.andEqualTo("parentId",cmsChannelCondition.getParentId());
		}
		return cmsChannelMapper.selectByExample(example);
	}
	
	@Override
	public PageBean<CmsChannel> selectChannelByPaging(Integer pageCurrent, Integer pageSize, String sort, String order, CmsChannelCondition cmsChannelCondition) {

		List<CmsChannel> userList;
		//分页处理
		List<OrderBy> orderBies = new ArrayList<>();
		orderBies.add(new OrderBy("createTime", "create_time"));
		orderBies.add(new OrderBy("updateTime", "update_time"));

		OrderByUtil  orderByUtil = new OrderByUtil();
		String orderBy = orderByUtil.getOrderBy(orderBies, sort, order);
		PageHelper.startPage(pageCurrent, pageSize);
		
		Example example = new Example(CmsChannel.class);
		if(!StringUtils.isEmpty(orderBy)){
			example.setOrderByClause(orderBy);
		}
		Criteria criteria = example.createCriteria();
		if(!StringUtils.isEmpty(cmsChannelCondition.getName())){
			criteria.andLike("name","%"+cmsChannelCondition.getName()+"%");
		}
		if(cmsChannelCondition.getBeginCreateTime()!=null || cmsChannelCondition.getEndCreateTime()!=null){
			criteria.andBetween("createTime", cmsChannelCondition.getBeginCreateTime(), cmsChannelCondition.getEndCreateTime());
		}
		userList = cmsChannelMapper.selectByExample(example);

		//取记录总条数
		PageInfo<CmsChannel> pageInfo = new PageInfo<>(userList);
		
		return new PageBean<>(pageInfo.getTotal(), pageCurrent, pageSize, userList);
	}
	

	@Override
	public int createCmsChannel(CmsChannel cmsChannel) throws Exception {

		Long parentId = cmsChannel.getParentId();

		CmsChannel cmsChannelCondition = new CmsChannel();
		cmsChannelCondition.setCode(cmsChannel.getCode());
		CmsChannel sysDictionaryDataTest = cmsChannelMapper.selectOne(cmsChannelCondition);
		if(sysDictionaryDataTest!=null){
			throw new CodeMultipleException("Code multiple error!");
		}

		if(!StringUtils.isEmpty(parentId)){
			CmsChannel cmsChannelParent = getChannelById(parentId);
			if(cmsChannelParent==null){
				throw new ParentNotFoundException("Parent not found!");
			}
		}

		int count = cmsChannelMapper.insertSelective(cmsChannel);
		if(count >0){
			updateHasChildrenToParent( parentId);
		}
		return count;

	}

	private int selectCountByParentId(Long parentId) {
		CmsChannel cmsChannel = new CmsChannel();
		cmsChannel.setParentId(parentId);
		return cmsChannelMapper.selectCount(cmsChannel);
	}



	/**
	 * 修改父级是否含子级
	 * @param parentId 父资源id
	 */
	private void  updateHasChildrenToParent(Long parentId){
		if(!StringUtils.isEmpty(parentId)){
			CmsChannel cmsChannel = new CmsChannel();
			cmsChannel.setId(parentId);
			if(selectCountByParentId(parentId)>0) {
				cmsChannel.setHasChildren(true);
			}else{
				cmsChannel.setHasChildren(false);
			}
			cmsChannelMapper.updateByPrimaryKeySelective(cmsChannel);
		}
	}

	@Override
	public CmsChannel selectOne(CmsChannel cmsChannel) {
		return cmsChannelMapper.selectOne(cmsChannel);
	}

	@Override
	public int updateChannel(CmsChannel cmsChannel) throws Exception {
		CmsChannel cmsChannelCondition = new CmsChannel();
		cmsChannelCondition.setCode(cmsChannel.getCode());
		CmsChannel cmsChannelTest = cmsChannelMapper.selectOne(cmsChannelCondition);
		if(cmsChannelTest!=null && !Objects.equals(cmsChannel.getId(), cmsChannelTest.getId())){
			throw new CodeMultipleException("Code multiple error!");
		}

		CmsChannel cmsChannelOld = getChannelById(cmsChannel.getId());

		Long parentId = cmsChannel.getParentId()==null?0:cmsChannel.getParentId();
		if(parentId!=0){

			//获取修改的父级资源
			CmsChannel cmsChannelParent = getChannelById(parentId);
			if(cmsChannelParent==null){
				throw new ParentNotFoundException("Parent not found!");
			}
			if (selectCountByParentId(cmsChannelOld.getId()) > 0) {
				Example example = new Example(CmsChannel.class);
				Example.Criteria criteria = example.createCriteria();
				criteria.andEqualTo("parentId",cmsChannelOld.getId());
				List<CmsChannel> cmsChannelList = cmsChannelMapper.selectByExample(example);
				if (!cmsChannelList.isEmpty()) {
					for(CmsChannel cmsChannel_:cmsChannelList){
						if(Objects.equals(cmsChannel_.getId(), parentId)){
							cmsChannelParent.setParentId(cmsChannelOld.getParentId());
							cmsChannelMapper.updateByPrimaryKeySelective(cmsChannelParent);
						}else{
							recursiveCheckParentIsChildren(cmsChannelOld.getParentId(),cmsChannel.getParentId(),cmsChannel,cmsChannelParent);
						}
					}
				}
			}
		}
		if(selectCountByParentId(cmsChannel.getId())>0) {
			cmsChannel.setHasChildren(true);
		}else{
			cmsChannel.setHasChildren(false);
		}
		int count = cmsChannelMapper.updateByPrimaryKeySelective(cmsChannel);
		if(count<=0){
			return count;
		}
		updateHasChildrenToParent(parentId);
		if(cmsChannelOld!=null){
			updateHasChildrenToParent(cmsChannelOld.getParentId());
		}
		return count;
	}


	/**
	 * 迭代检查选择的上级id是否是自己的子级
	 * @param parentIdOld 原上级id
	 * @param parentIdNew	新上级id
	 * @param cmsChannelChild 子机构
	 * @param cmsChannelParent 父机构
	 */
	private void recursiveCheckParentIsChildren(Long parentIdOld, Long parentIdNew, CmsChannel cmsChannelChild, CmsChannel cmsChannelParent){
		if (selectCountByParentId(cmsChannelChild.getId()) > 0) {
			Example example = new Example(CmsChannel.class);
			Example.Criteria criteria = example.createCriteria();
			criteria.andEqualTo("parentId",cmsChannelChild.getId());
			List<CmsChannel> cmsChannelList = cmsChannelMapper.selectByExample(example);
			if (!cmsChannelList.isEmpty()) {
				for(CmsChannel cmsChannel:cmsChannelList){
					if(Objects.equals(cmsChannel.getId(), parentIdNew)){
						cmsChannelParent.setParentId(parentIdOld);
						cmsChannelMapper.updateByPrimaryKeySelective(cmsChannelParent);
					}else {
						recursiveCheckParentIsChildren(parentIdOld, parentIdNew, cmsChannel, cmsChannelParent);
					}
				}
			}
		}
	}

	@Override
	public int deleteChannel(Long id) {
		return cmsChannelMapper.deleteByPrimaryKey(id);
	}
	
}
